﻿#include "HalconWindowWidget.h"
#include <QMouseEvent>
#include <QDebug>
#include <algorithm>


HalconWindowWidget::HalconWindowWidget(QWidget *parent)
    : QWidget{parent}
{
    HalconCpp::OpenWindow(0,0,this->width(),this->height(), (Hlong)this->winId(),"visible","",&mWindow);
    SetDraw(mWindow,"margin");
    SetLineWidth(mWindow,2);
    SetColor(mWindow,"red");

    HalconCpp::OpenWindow(0,0,this->width(),this->height(), (Hlong)this->winId(),"invisible","",&mWindowHide);
    SetDraw(mWindowHide,"margin");
    SetLineWidth(mWindowHide,2);
    SetColor(mWindowHide,"red");
}

void HalconWindowWidget::setImage(const HObject &img)
{
    HalconCpp::CopyImage(img, &mImage);
    fixedImage();
}

void HalconWindowWidget::dispObj(const HObject &obj)
{
    DispObj(obj, mWindowHide);
    updateWindow();
}

void HalconWindowWidget::updateWindow()
{
    CopyRectangle(mWindowHide,mWindow,0,0,this->height(), this->width(),0,0);
}

void HalconWindowWidget::addOneObj(const HObject& obj)
{
    DispObj(obj, mWindowHide);
}

void HalconWindowWidget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::MouseButton::LeftButton){
        mPointStart = event->pos();
        mIsMouseDown = true;
    } else if(event->button() == Qt::MouseButton::RightButton){
        fixedImage();
    }
}

void HalconWindowWidget::mouseMoveEvent(QMouseEvent *event)
{
    if(mIsMouseDown && this->rect().contains(event->pos())){
        mPointEnd = event->pos();//鼠标在控件上的坐标
        moveWnd();
        mPointStart = mPointEnd;
    }else{
        QPointF posDifImage = (event->pos() * mScaleMin) * (mScaleMin / mScale);
        int row = mShowPartRow0 + posDifImage.y();
        int col = mShowPartCol0 + posDifImage.x();
        HTuple value, length;
        GetGrayval(mImage, row, col, &value);
        TupleLength(value, &length);
        if(length.I() > 1){
            emit sigPosRGBValue(QPoint(col, row), QColor(value[0].I(),value[1].I(),value[2].I()));
        } else {
            int gray = value.I();
            emit sigPosRGBValue(QPoint(col, row), QColor(gray,gray,gray));
        }
    }
}

void HalconWindowWidget::mouseReleaseEvent(QMouseEvent *event)
{
    mIsMouseDown = false;
}

void HalconWindowWidget::wheelEvent(QWheelEvent *event)
{
    short zDelta =short(event->delta());
    if (zDelta > 0){
        mScale *= 1.05;
        if (mScale > mScaleMax){
            mScale = mScaleMax;
        }
    }else if (zDelta < 0){
        mScale /= 1.05;
        if (mScale < mScaleMin){
            mScale = mScaleMin;
        }
    }
    scaleImage();
}

void HalconWindowWidget::resizeEvent(QResizeEvent *event)
{
    HTuple len;
    TupleLength(mWindow,&len);
    if(len>0){
        SetWindowExtents(mWindow, 0, 0, this->width(),this->height());
    } else {
        HalconCpp::OpenWindow(0,0,this->width(),this->height(), (Hlong)this->winId(),"visible","",&mWindow);
    }

    TupleLength(mWindowHide,&len);
    if(len>0){
        SetWindowExtents(mWindowHide, 0, 0, this->width(),this->height());
    } else {
        HalconCpp::OpenWindow(0,0,this->width(),this->height(), (Hlong)this->winId(),"invisible","",&mWindowHide);
    }

    fixedImage();
}

void HalconWindowWidget::scaleImage()
{
    float center_col = (mShowPartCol0 + mShowPartCol1) / 2;
    float center_row = (mShowPartRow0 + mShowPartRow1) / 2;

    float imageWidth = HImage(mImage).Width().I();
    float imageHeight = HImage(mImage).Height().I();

    float showWidth = (this->width() * mScaleMin) * (mScaleMin / mScale);
    float showHeight = (this->height() * mScaleMin) * (mScaleMin / mScale);

    float showRow = center_row - showHeight / 2;
    float showCol = center_col - showWidth / 2;

    mShowPartCol0 = showCol;
    mShowPartRow0 = showRow;
    mShowPartCol1 = showCol + showWidth;
    mShowPartRow1 = showRow + showHeight;
    displayImage();

}

void HalconWindowWidget::moveWnd()
{
    QPointF posMov = mPointEnd - mPointStart;
    float imageWidth = HImage(mImage).Width().I();
    float imageHeight = HImage(mImage).Height().I();

    float showWidth = mShowPartCol1 - mShowPartCol0;
    float showHeight = mShowPartRow1 - mShowPartRow0;

    float showRow = mShowPartRow0 - posMov.y();
    float showCol = mShowPartCol0 - posMov.x();

    mShowPartCol0 = showCol;
    mShowPartRow0 = showRow;
    mShowPartCol1 = showCol + showWidth;
    mShowPartRow1 = showRow + showHeight;
    displayImage();
}

void HalconWindowWidget::fixedImage()
{
    float imageWidth = HImage(mImage).Width().I();
    float imageHeight = HImage(mImage).Height().I();
    //初始化放大倍数
    float width_ratio = imageWidth / this->width();
    float height_ratio = imageHeight / this->height();

    mScale = (std::max)(width_ratio, height_ratio);
    mScaleMax = mScale * 20;
    mScaleMin = mScale;

    float showWidth = this->width() * mScale;
    float showHeight = this->height() * mScale;

    mShowPartCol0 = (imageWidth - showWidth) / 2;
    mShowPartRow0 = (imageHeight - showHeight) / 2;
    mShowPartCol1 = mShowPartCol0 + showWidth;
    mShowPartRow1 = mShowPartRow0 + showHeight;
    displayImage();
}

void HalconWindowWidget::displayImage()
{
    ClearWindow(mWindowHide);
    SetPart(mWindowHide,mShowPartRow0,mShowPartCol0,mShowPartRow1, mShowPartCol1);
    HalconCpp::DispObj(mImage,mWindowHide);
    updateWindow();
}



